home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- ** **
- ** Module: TinselMipMap.c **
- ** **
- ** Purpose: Support file for mipmapping **
- ** **
- ** Author: Mike W. Kelley **
- ** **
- ** 2/3/95 Revised for 0.9 SDK release **
- ** **
- ** Copyright (C) 1994-95 Apple Computer, Inc. All rights reserved. **
- ** **
- *****************************************************************************/
-
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- #include <stdio.h>
-
- /* Macintosh */
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <OSEvents.h>
- #include <DiskInit.h>
- #include <Packages.h>
-
- /* Project */
- #include "Drive3D.h"
- #include "TinselTest.h"
-
- /*******************************************************************************************
- *
- * Create the mipmap for 'pixmap', and load it into 'texture'. Returns NULL on error.
- *
- ******************************************************************************************/
-
- TQATexture *CreateMipMapTexture (
- TQAEngine *engine,
- TexturePixel *pixmap,
- long rowBytes,
- long widthNBits,
- long heightNBits)
- {
- long nImages;
- long width, height;
- long nPixels;
- TexturePixel *mipmap;
- TQAImage images [20]; /* Maximum conceivable number of TQAImages! */
- long i;
- long x, y;
- long oneHalf;
- TQATexture *texture;
- TQAError status;
-
- /*
- * Allocate working space for the mip map images (starting with the
- * 2^(widthNBits-1) x 2^(heightNBits-1) map), and for the array of
- * TQAImages that describe the mip map and the parent map.
- */
-
- nImages = ((widthNBits > heightNBits) ? widthNBits : heightNBits) + 1;
-
- width = 1 << (widthNBits - 1); /* ??? Doesn't work for nBits == 0 */
- height = 1 << (heightNBits - 1); /* ??? Doesn't work for nBits == 0 */
-
- for (i = nImages - 1, nPixels = 0; i-- > 0; /* Nothing */)
- {
- nPixels += width * height;
-
- width >>= 1;
- height >>= 1;
-
- if (width == 0)
- {
- width = 1;
- }
- if (height == 0)
- {
- height = 1;
- }
- }
-
- if ( ! (mipmap = malloc (sizeof (*pixmap) * nPixels)))
- {
- return (NULL);
- }
-
- /*
- * Fill in the TQAImage info.
- */
-
- images[0].width = 1 << widthNBits;
- images[0].height = 1 << heightNBits;
- images[0].pixmap = pixmap;
- images[0].rowBytes = rowBytes;
-
- width = 1 << (widthNBits - 1); /* ??? Doesn't work for nBits == 0 */
- height = 1 << (heightNBits - 1); /* ??? Doesn't work for nBits == 0 */
-
- for (i = 1; i < nImages; ++i)
- {
- images[i].width = width;
- images[i].height = height;
- images[i].pixmap = mipmap;
- images[i].rowBytes = width * sizeof (*mipmap);
-
- mipmap += width * height;
-
- width >>= 1;
- height >>= 1;
-
- if (width == 0)
- {
- width = 1;
- }
- if (height == 0)
- {
- height = 1;
- }
- }
-
- /*
- * oneHalf is used to round off the box filter of four pixels.
- */
-
- oneHalf = 4 / 2;
-
- /*
- * Create the mipmapped images.
- */
-
- for (i = 1; i < nImages; ++i)
- {
- TQAImage *prevImage, *image;
- long sourceRowBytes, targetRowBytes;
- unsigned char *sourceLine0, *sourceLine1;
- unsigned char *targetLine;
-
- prevImage = &images [i - 1];
- image = &images [i];
-
- sourceLine0 = prevImage->pixmap;
-
- if (prevImage->height == 1)
- {
- /*
- * Source image is height 1 (widthNBits must be greater than heightNBits).
- * Make sourceLine1 duplicate sourceLine0, and set sourceRowBytes to 0 so we
- * just keep re-reading the single source line.
- */
-
- sourceRowBytes = 0;
- sourceLine1 = sourceLine0;
- }
- else
- {
- /*
- * Normal case. sourceLine1 points one scanline above sourceLine0.
- */
-
- sourceRowBytes = prevImage->rowBytes;
- sourceLine1 = sourceLine0 + sourceRowBytes;
- }
-
- targetRowBytes = image->rowBytes;
- targetLine = image->pixmap;
-
- for (y = image->height; y-- > 0; /* Nothing */)
- {
- unsigned char *sourcePixel0, *sourcePixel1;
- unsigned char *targetPixel;
-
- sourcePixel0 = sourceLine0;
- sourcePixel1 = sourceLine1;
- targetPixel = targetLine;
-
- if (prevImage->width == 1)
- {
- /*
- * Source image has width 1 (heightNBits must be greater than widthNBits).
- * Use a special inner loop that doesn't advance past the first pixel of
- * the source lines.
- */
-
- for (x = image->width; x-- > 0; /* Nothing */)
- {
- long a, r, g, b;
-
- /*
- * Read and average two pixels from source into target.
- */
-
- a = sourcePixel0 [0] + (oneHalf >> 1);
- r = sourcePixel0 [1] + (oneHalf >> 1);
- g = sourcePixel0 [2] + (oneHalf >> 1);
- b = sourcePixel0 [3] + (oneHalf >> 1);
-
- a += sourcePixel1 [0];
- r += sourcePixel1 [1];
- g += sourcePixel1 [2];
- b += sourcePixel1 [3];
-
- *targetPixel++ = a >> 1;
- *targetPixel++ = r >> 1;
- *targetPixel++ = g >> 1;
- *targetPixel++ = b >> 1;
- }
- }
- else
- {
- /*
- * Source image has at least width 2. This is the normal case.
- */
-
- for (x = image->width; x-- > 0; /* Nothing */)
- {
- long a, r, g, b;
-
- /*
- * Read and average four pixels from source into target.
- */
-
- a = *sourcePixel0++ + oneHalf;
- r = *sourcePixel0++ + oneHalf;
- g = *sourcePixel0++ + oneHalf;
- b = *sourcePixel0++ + oneHalf;
-
- a += *sourcePixel1++;
- r += *sourcePixel1++;
- g += *sourcePixel1++;
- b += *sourcePixel1++;
-
- a += *sourcePixel0++;
- r += *sourcePixel0++;
- g += *sourcePixel0++;
- b += *sourcePixel0++;
-
- a += *sourcePixel1++;
- r += *sourcePixel1++;
- g += *sourcePixel1++;
- b += *sourcePixel1++;
-
- *targetPixel++ = a >> 2;
- *targetPixel++ = r >> 2;
- *targetPixel++ = g >> 2;
- *targetPixel++ = b >> 2;
- }
- }
- sourceLine0 += (sourceRowBytes << 1);
- sourceLine1 += (sourceRowBytes << 1);
- targetLine += targetRowBytes;
- }
- }
-
- status = QATextureNew (engine, kQATexture_Mipmap, kQAPixel_RGB32, images, &texture);
- if (status != kQANoErr)
- {
- return (NULL);
- }
-
- return (texture);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-